﻿using jvm.classfile.constantpool;
using jvm.rtda.heap.clazz.method;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace jvm.rtda.heap.clazz.cp
{
    class MethodRef : MemberRef
    {
        private JMethod method; // 指针缓存

        public MethodRef(JConstantPool cp, ConstantMemberrefInfo memberrefInfo) : base(cp, memberrefInfo)
        {
        }

        public JMethod ResolvedMethod()
        {
            if (method == null)
            {
                ResolveMethodRef();
            }
            return method;
        }

        private void ResolveMethodRef()
        {
            JClass d = pool.jClass;
            JClass c = ResolvedClass();
            if (c.Is(AccessFlags.ACC_INTERFACE))
            {
                Console.WriteLine("java.lang.IncompatibleClassChangeError");
                Environment.Exit(0);
            }

            JMethod method = LookUpMethod(c, name, descriptor);
            if (method == null)
            {
                Console.WriteLine("java.lang.NoSuchMethodError");
                Environment.Exit(0);
            }
            if (!method.IsAccessibleTo(d))
            {
                Console.WriteLine("java.lang.IllegalAccessError");
                Environment.Exit(0);
            }
            this.method = method;
        }

        JMethod LookUpMethod(JClass jClass, string name, string descriptor)
        {
            JMethod method = MethodLookUp.LookUpMethodInClass(jClass, name, descriptor);
            if (method == null)
            {
                method = MethodLookUp.LookUpMethodInInterfaces(jClass.interfaces, name, descriptor);
            }
            return method;
        }
    }
}
